<template>
  <div class="cesium-draw">
    <div id="cesium-drawer" />

    <a-dropdown>
      <a class="ant-dropdown-link tools" @click.prevent>
        {{ drawingModeText }}
        <DownOutlined />
      </a>

      <template #overlay>
        <a-menu @click="handleMenuClick">
          <a-menu-item v-for="(e, index) in types" :key="e.key">{{ e.text }}</a-menu-item>
        </a-menu>
      </template>
    </a-dropdown>

    <div class="mouse-postion">{{ nowPostion.wgs84 }}</div>

    <div class="chart-container" v-show="!!chartOptions"><div id="profileChart" /></div>
  </div>
</template>

<script>
//参考： https://xiaozhuanlan.com/topic/2108573649
// https://blog.csdn.net/weixin_40184249/article/details/91896181
import { DownOutlined, EditOutlined } from '@ant-design/icons-vue';
import { defineComponent, ref, onMounted, h } from 'vue';
import * as Cesium from '@cesium/Source/Cesium.js';
import * as echarts from 'echarts';
import MousePosition from '../utils/mousePosition.js';
import { distanceCartesian, distanceCartographic } from '../utils/measure/utils';
// import { measureLineSpace } from '../utils/measure/line';
// import { measureAreaSpace } from '../utils/measure/area';

export default defineComponent({
  components: { DownOutlined, EditOutlined },
  setup() {
    return {
      viewer: null
    };
  },
  data() {
    return {
      drawingMode: 'polygon',
      types: [
        {
          text: '长度',
          key: 'line'
          // fn: measureLineSpace
        },
        {
          text: '面积（多边形）',
          key: 'polygon'
          // fn: measureAreaSpace
        },
        {
          text: '面积（圆）',
          key: 'circle'
          // fn: measureLineSpace
        },
        {
          text: '面积（矩形）',
          key: 'rectangle'
          // fn: measureLineSpace
        }
      ],
      nowPostion: {},
      chartOptions: null
    };
  },
  computed: {
    drawingModeText() {
      const { drawingMode, types } = this;
      return types.filter(e => e.key === drawingMode)[0].text;
    }
  },
  watch: {
    drawingMode(t) {
      if (this.viewer) {
        // const typ = this.getType(t);
        // typ.fn(this.viewer);
      }
    },
    chartOptions() {
      this.updateChart();
    }
  },
  mounted() {
    this.initViewer();
  },
  beforeUnmount() {
    if (this.viewer) {
      this.viewer.destroy();
    }
  },
  methods: {
    updateChart() {
      const { chartOptions } = this;
      if (!chartOptions) return;

      var dom = document.getElementById('profileChart');
      var myChart = echarts.init(dom, 'dark');
      myChart.setOption(chartOptions);
    },
    getType(k) {
      return this.types.filter(e => e.key === k)[0];
    },
    handleMenuClick(e) {
      // this.terminateShape();
      this.drawingMode = e.key;
    },
    onViewerInited(viewer) {
      let vm = this;
      new MousePosition(viewer, pos => {
        vm.nowPostion = pos;
      });
      // this.drawingMode = 'line';
      // measureLineSpace(viewer);

      //取消左键双击事件
      viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
      //具体事件的实现
      var ellipsoid = viewer.scene.globe.ellipsoid;
      var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
      var start, end;
      var profile = {
        arrHB: [],
        arrPoint: [],
        arrLX: [],
        ponits: [],
        distance: 0
      };
      var myChart;
      var draw = function(drawingMode) {
        var entityPolygon = null;
        var points = null;
        //取消左键双击事件
        viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
        //淹没分析entity
        function createPoint(worldPosition) {
          var point = viewer.entities.add({
            position: worldPosition,
            point: {
              pixelSize: 10,
              color: Cesium.Color.YELLOW,
              //disableDepthTestDistance: Number.POSITIVE_INFINITY,
              heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
            }
          });
          points = point;
          return point;
        }
        var drawingMode = drawingMode;
        function drawShape(positionData) {
          var shape;
          if (drawingMode === 'line') {
            shape = viewer.entities.add({
              polyline: {
                positions: positionData,
                clampToGround: true,
                arcType: Cesium.ArcType.RHUMB,
                material: Cesium.Color.GREEN,
                width: 5
                //zIndex:1
              }
              //,show:false
            });
          } else if (drawingMode === 'polygon') {
            shape = viewer.entities.add({
              polygon: {
                hierarchy: positionData,
                material: new Cesium.ColorMaterialProperty(Cesium.Color.LIGHTSKYBLUE.withAlpha(0.7))
              }
            });
          }
          return shape;
        }
        var activeShapePoints = [];
        var activeShape;
        var floatingPoint;
        handler.setInputAction(function(event) {
          if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) {
            console.log('This browser does not support polylines on terrain.');
            return;
          }
          // 使用viewer.scene.pickPosition` 来代替`viewer.camera.pickEllipsoid` 这样当鼠标掠过terrain能得到正确的坐标
          var earthPosition = viewer.scene.pickPosition(event.position);
          if (Cesium.defined(earthPosition)) {
            if (activeShapePoints.length === 0) {
              start = earthPosition;
              floatingPoint = createPoint(earthPosition);
              activeShapePoints.push(earthPosition);
              var dynamicPositions = new Cesium.CallbackProperty(function() {
                return activeShapePoints;
              }, false);
              activeShape = drawShape(dynamicPositions);
            }
            //计算距离并且进行叠加
            profile.distance = profile.distance + distanceCartesian(activeShapePoints[activeShapePoints.length - 1], earthPosition);
            activeShapePoints.push(earthPosition);
            createPoint(earthPosition);
          }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        handler.setInputAction(function(event) {
          if (Cesium.defined(floatingPoint)) {
            var newPosition = viewer.scene.pickPosition(event.endPosition);
            if (Cesium.defined(newPosition)) {
              floatingPoint.position.setValue(newPosition);
              activeShapePoints.pop();
              activeShapePoints.push(newPosition);
            }
          }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        function terminateShape() {
          activeShapePoints.pop();
          entityPolygon = drawShape(activeShapePoints);
          viewer.entities.remove(floatingPoint);
          viewer.entities.remove(activeShape);
          entityPolygon = null;
          floatingPoint = undefined;
          activeShape = undefined;
          activeShapePoints = [];
          profile = {
            arrHB: [],
            arrPoint: [],
            arrLX: [],
            ponits: [],
            distance: 0
          };
        }
        handler.setInputAction(function(event) {
          var length = activeShapePoints.length - 1;
          end = activeShapePoints[length];
          var data = profileAnalyse(start, end);
          console.log(data);
          setEchartsData(data);
          terminateShape();
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
      };
      //剖面分析
      function profileAnalyse(start, end) {
        var startPoint = Cesium.Cartographic.fromCartesian(start);
        var endPoint = Cesium.Cartographic.fromCartesian(end);
        profile.arrLX.push(0);
        profile.ponits.push(startPoint);
        // profile.arrPoint.push(getDegrees(startPoint));
        profile.arrPoint.push(startPoint);
        profile.arrHB.push(startPoint.height);

        // 插值100个点，点越多模拟越精确，但是效率会低
        var count = 100;
        let result = new Cesium.Cartesian3();
        for (var i = 1; i < count; i++) {
          var cart = Cesium.Cartesian3.lerp(start, end, i / count, result);
          var cartographicCart = Cesium.Cartographic.fromCartesian(cart);
          var disc = distanceCartographic(profile.ponits[i - 1], cartographicCart);

          profile.distance = profile.distance + disc;
          profile.ponits.push(cartographicCart);
          profile.arrLX.push(profile.arrLX[i - 1] + disc);

          profile.arrPoint.push(getDegrees(cart));
          profile.arrHB.push(cartographicCart.height);
        }

        profile.ponits.push(endPoint);
        profile.arrLX.push(profile.arrLX[profile.arrLX.length - 1] + distanceCartographic(profile.ponits[profile.ponits.length - 1], endPoint));
        // profile.arrPoint.push(getDegrees(endPoint));
        profile.arrPoint.push(endPoint);
        profile.arrHB.push(endPoint.height);

        return profile;
      }

      //世界坐标转换为经纬度
      function getDegrees(cart) {
        var cartographic = ellipsoid.cartesianToCartographic(cart);
        var lat = Cesium.Math.toDegrees(cartographic.latitude);
        var lng = Cesium.Math.toDegrees(cartographic.longitude);
        var alt = cartographic.height;
        return { x: lng, y: lat, z: alt };
      }

      //经纬度保留两位小数
      function strFormat(str) {
        var strString = str.toString();
        var strs = strString.slice(0, strString.indexOf('.') + 3);
        return strs;
      }

      //设置Echart数据
      function setEchartsData(e) {
        if (null != e && null != e.arrPoint) {
          // console.log(e.arrHB.value);
          var t = e.arrPoint;
          var chartOptions = {
            grid: {
              left: 10,
              right: 10,
              top: 20,
              bottom: 10,
              containLabel: true
            },
            // dataZoom: [
            //   {
            //     type: 'inside',
            //     throttle: 50
            //   }
            // ],
            tooltip: {
              trigger: 'axis',
              axisPointer: {
                type: 'cross'
              },
              padding: [5, 10],
              formatter: function(e) {
                var a = '';
                if (0 == e.length) return a;
                let o = e[0];
                // e[0].value;
                // console.log(e);
                var r = t[o.dataIndex];
                // console.log(r);
                return (a +=
                  '所在位置&nbsp;' +
                  strFormat(r.x || 0) +
                  ',' +
                  strFormat(r.y || 0) +
                  '<br />距起点&nbsp;<label>' +
                  Number(o.axisValue || 0).toFixed(2) +
                  '</label><br />' +
                  o.seriesName +
                  "&nbsp;<label style='color:" +
                  o.color +
                  ";'>" +
                  o.value.toFixed(2) +
                  '</label><br />');
              }
            },
            xAxis: [
              {
                name: '行程',
                type: 'category',
                boundaryGap: !1,
                axisLine: {
                  show: true
                },
                axisLabel: {
                  show: true
                },
                data: e.arrLX
              }
            ],
            yAxis: [
              {
                type: 'value',
                axisLabel: {
                  // rotate: 60,
                  formatter: '{value} 米'
                }
              }
            ],
            series: [
              {
                name: '高程值',
                type: 'line',
                // smooth: !0,
                symbol: 'none',
                sampling: 'average',
                itemStyle: {
                  normal: {
                    color: 'rgb(255, 70, 131)'
                  }
                },
                areaStyle: {
                  normal: {
                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                      {
                        offset: 0,
                        color: 'rgb(255, 158, 68)'
                      },
                      {
                        offset: 1,
                        color: 'rgb(255, 70, 131)'
                      }
                    ])
                  }
                },
                data: e.arrHB
              }
            ]
          };
          vm.chartOptions = chartOptions;
        }
      }
      draw('line');
    },
    initViewer() {
      let vm = this;
      Cesium.Ion.defaultAccessToken = $accessToken.default;
      var rectangle = new Cesium.Rectangle(
        Cesium.Math.toRadians(5.9993076),
        Cesium.Math.toRadians(-0.00025749207),
        Cesium.Math.toRadians(7.00078),
        Cesium.Math.toRadians(1.001215)
      );

      var terrainProvider = Cesium.createWorldTerrain();
      var viewer = new Cesium.Viewer('cesium-drawer', {
        animation: false,
        // baseLayerPicker: false,
        fullscreenButton: false,
        vrButton: false,
        homeButton: false,
        timeline: false,
        // imageryProvider: imgTileServiceImageryProviderCreator(),
        selectionIndicator: false,
        infoBox: false,
        // 注释时相当于使用默认地形，解开注释相当于使用全球地形
        terrainProvider
      });
      this.viewer = viewer;

      viewer.scene.globe.depthTestAgainstTerrain = true;

      // viewer.scene.camera.flyTo({ destination: rectangle });

      // // Zoom in to an area with mountains
      // viewer.camera.lookAt(Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0), new Cesium.Cartesian3(5000.0, 5000.0, 5000.0));
      // viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);

      // viewer.scene.camera.flyTo({
      //   destination: new Cesium.Cartesian3(-548184.7982559408, 5512367.059463563, 3173625.2210259973),
      //   orientation: {
      //     heading: 5.683499859605618,
      //     pitch: -0.3430291183891061,
      //     roll: 6.281444671468591
      //   }
      // });

      viewer.camera.setView({
        destination: new Cesium.Cartesian3(-548184.7982559408, 5512367.059463563, 3173625.2210259973),
        orientation: {
          heading: 5.683499859605618,
          pitch: -0.3430291183891061,
          roll: 6.281444671468591
        }
      });

      this.onViewerInited(viewer);
    }
  }
});
</script>

<style scoped lang="less">
.cesium-draw {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  color: white;

  .tools {
    position: absolute;
    top: 57px;
    left: 7px;
    font-size: 14px;
    padding: 8px 12px;
    line-height: 16px;
    color: white;
    z-index: 9999;
    background-color: rgba(40, 48, 60, 1);
    border-radius: 3px;
    opacity: 0.6;
    transition: all 500ms;
    &:hover {
      opacity: 0.8;
    }
  }

  #cesium-drawer {
    width: 100%;
    height: 100%;
    overflow: hidden;
    :deep(.cesium-viewer-bottom) {
      display: none !important;
    }
  }

  .mouse-postion {
    position: absolute;
    bottom: 10px;
    right: 10px;
    font-size: 14px;
    padding: 8px 12px;
    line-height: 16px;
    color: white;
    z-index: 9999;
    background-color: rgba(40, 48, 60, 1);
    border-radius: 3px;
    opacity: 0.8;
  }
}

.chart-container {
  position: absolute;
  bottom: 10px;
  left: 1em;
  background-color: rgba(0, 0, 0, 0.5);

  #profileChart {
    width: 600px;
    height: 300px;
  }
}
</style>
